import asyncio
import logging
import os
import sys
from datetime import datetime
from bson import ObjectId
from motor.motor_asyncio import AsyncIOMotorClient

# 添加项目根目录到 python path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.core.config import settings
from app.services.role_service import RoleService
from app.enums.role import SystemRole

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

async def migrate_roles():
    """
    迁移角色数据
    1. 初始化默认角色
    2. 迁移用户角色 (User.role -> User.system_roles)
    3. 迁移项目成员角色 (Project.members.role -> Project.members.roles)
    """
    logger.info("Starting role migration...")
    
    # 连接数据库
    client = AsyncIOMotorClient(settings.MONGODB_URL)
    db = client[settings.MONGODB_DATABASE]
    
    try:
        # 1. 初始化默认角色
        logger.info("Initializing default roles...")
        await RoleService.init_default_roles(db)
        
        # 获取角色映射 (code -> _id)
        roles = await db.roles.find().to_list(None)
        role_map = {r["code"]: str(r["_id"]) for r in roles}
        logger.info(f"Loaded {len(role_map)} roles: {list(role_map.keys())}")
        
        # 2. 迁移用户角色
        logger.info("Migrating users...")
        users = await db.users.find({}).to_list(None)
        migrated_users = 0
        
        for user in users:
            # 如果已经有 system_roles 且不为空，跳过（假设已迁移或新用户）
            if user.get("system_roles"):
                continue
                
            old_role = user.get("roles") # 以前是 roles: List[UserRole] 或 role: str? 
            # User模型定义是 roles: List[UserRole] (Step 110 view)
            # 但在数据库中可能存储为 list 或 string (取决于历史)
            # 假设是 list
            
            new_system_roles = []
            
            # 简单的迁移策略：
            # 如果包含 'admin' -> system_roles=['admin_id']
            # 否则 -> system_roles=['user_id']
            
            is_admin = False
            if isinstance(old_role, list):
                if "admin" in old_role:
                    is_admin = True
            elif isinstance(old_role, str):
                if old_role == "admin":
                    is_admin = True
            
            if is_admin:
                if "admin" in role_map:
                    new_system_roles.append(role_map["admin"])
            else:
                if "user" in role_map:
                    new_system_roles.append(role_map["user"])
            
            # 更新用户
            await db.users.update_one(
                {"_id": user["_id"]},
                {"$set": {"system_roles": new_system_roles}}
            )
            migrated_users += 1
            
        logger.info(f"Migrated {migrated_users} users.")
        
        # 3. 迁移项目成员角色
        logger.info("Migrating projects...")
        projects = await db.projects.find({}).to_list(None)
        migrated_projects = 0
        
        for project in projects:
            members = project.get("members", [])
            updated_members = []
            changed = False
            
            for member in members:
                # 检查是否需要迁移
                if "roles" in member and member["roles"]:
                    updated_members.append(member)
                    continue
                
                old_role = member.get("role")
                new_roles = []
                
                if old_role:
                    # 映射旧角色到新角色ID
                    # 处理一些特殊情况或直接映射
                    role_code = old_role
                    if role_code == "manager":
                        role_code = "project_manager"
                    
                    if role_code in role_map:
                        new_roles.append(role_map[role_code])
                    else:
                        logger.warning(f"Unknown role code '{old_role}' in project {project['_id']}, defaulting to 'viewer'")
                        if "viewer" in role_map:
                            new_roles.append(role_map["viewer"])
                
                # 如果没有角色，默认为 viewer
                if not new_roles and "viewer" in role_map:
                    new_roles.append(role_map["viewer"])
                
                member["roles"] = new_roles
                # 可以选择删除 old 'role' 字段，或者保留
                # member.pop("role", None) 
                updated_members.append(member)
                changed = True
            
            if changed:
                await db.projects.update_one(
                    {"_id": project["_id"]},
                    {"$set": {"members": updated_members}}
                )
                migrated_projects += 1
                
        logger.info(f"Migrated {migrated_projects} projects.")
        logger.info("Migration completed successfully.")
        
    except Exception as e:
        logger.error(f"Migration failed: {str(e)}")
        raise
    finally:
        client.close()

if __name__ == "__main__":
    asyncio.run(migrate_roles())
